home *** CD-ROM | disk | FTP | other *** search
/ Font Garden / Font Garden (Walnut Creek) (October 1995) (1995).iso / pc / fontutil / compress / fontconv.sha < prev    next >
Encoding:
Text File  |  1995-06-30  |  19.1 KB  |  736 lines

  1.  7-Jun-86 09:48:50-PDT,20228;000000000001
  2. Return-Path: <jdb@s1-c.arpa>
  3. Received: from s1-c.arpa by SUMEX-AIM.ARPA with TCP; Sat 7 Jun 86 09:48:39-PDT
  4. Received: by s1-c.arpa id AA12054; Sat, 7 Jun 86 09:48:24 PDT
  5.     id AA12054; Sat, 7 Jun 86 09:48:24 PDT
  6. Date: Sat, 7 Jun 86 09:48:24 PDT
  7. From: John Bruner <jdb@s1-c.arpa>
  8. Message-Id: <8606071648.AA12054@s1-c.arpa>
  9. To: info-mac@sumex-aim.arpa
  10. Subject: Mac font to vfont (Sun screen) font converter
  11.  
  12. "fontcvt" is a UNIX program I wrote one day while waiting for my hard disc
  13. to be repaired.  It extracts FONT resources from a Macintosh resource file
  14. and creates font files in vfont format.  These fonts can be used as Sun
  15. screen fonts.  (Theoretically they could also be used as Versatec
  16. printer fonts, but the difference in resolution makes all but the largest
  17. Mac fonts too small for the Versatec.)
  18. --
  19.   John Bruner (S-1 Project, Lawrence Livermore National Laboratory)
  20.   MILNET: jdb@mordor [jdb@s1-c.ARPA]    (415) 422-0758
  21.   UUCP: ...!ucbvax!dual!mordor!jdb     ...!seismo!mordor!jdb
  22. ---------------------------------------------------------------------------
  23. : This is a shar archive.  Extract with sh, not csh.
  24. echo x - README
  25. sed -e 's/^X//' > README << '!EOF!README!'
  26. X"fontcvt" extracts resources of type "FONT" from Macintosh resource
  27. Xfiles and converts the fonts into (Sun) vfont format.  (The header
  28. Xfile on Suns defines two constants which the 4.2BSD header file
  29. Xdoes not:
  30. X
  31. X    #define    VFONT_MAGIC    0436
  32. X    #define    NUM_DISPATCH    256
  33. X
  34. X)  The resulting fonts can then be used with Sun Windows.
  35. X
  36. XThe source is divided into two files.  "fontcvt.c" contains the
  37. Xactual font converter.  "resmgr.c" is a quick-and-dirty library of
  38. Xroutines for (read-only) access to resource files.
  39. X
  40. XTo run the converter, upload the resource fork of a Macintosh font
  41. Xfile to the host.  Execute the command
  42. X
  43. X    $ fontcvt resourcefile
  44. X
  45. Xwhere "resourcefile" is the resource file.  It will extract all
  46. XFONT resources and create files in the current directory with
  47. Xfilenames of the form "fontname.size", where "fontname" is the
  48. Xfont name (in lower-case with whitespace converted to underscores)
  49. Xand "size" is the point size.
  50. X
  51. XNOTE: Some Macintosh fonts are copyrighted, and others may be
  52. Xprotected by license agreements; hence, it may be illegal to use
  53. Xand/or distribute them in vfont format.  "fontcvt" is intended for
  54. Xlegal use only.
  55. X
  56. X"fontcvt" tries to cope with byte-order issues, but it is unclear
  57. Xhow well it will work on a little-endian machine (e.g. a VAX).  Also
  58. Xnote that byte order is an issue when vfont-format files are
  59. Xtransported between little-endian and big-endian machines.  (The
  60. Xprogram "/usr/lib/vswap" on Suns can be used to perform the necessary
  61. Xconversion.)
  62. !EOF!README!
  63. echo x - Makefile
  64. sed -e 's/^X//' > Makefile << '!EOF!Makefile!'
  65. X#! /bin/make -f
  66. X
  67. XCFLAGS    =    -O
  68. X
  69. Xfontcvt:    fontcvt.o resmgr.o
  70. X    $(CC) $(CFLAGS) -o fontcvt fontcvt.o resmgr.o
  71. !EOF!Makefile!
  72. echo x - fontcvt.c
  73. sed -e 's/^X//' > fontcvt.c << '!EOF!fontcvt.c!'
  74. X/*
  75. X *    fontcvt - convert Macintosh fonts to vfont format
  76. X */
  77. X
  78. X#include <sys/types.h>
  79. X#include <netinet/in.h>
  80. X#include <ctype.h>
  81. X#include <strings.h>
  82. X#include <vfont.h>
  83. X
  84. X#define    SZ_VFHDR    (5*sizeof(short))
  85. X
  86. Xextern char *malloc();
  87. Xextern char **getresource(), **getindresource();
  88. Xextern unsigned long sizeresource();
  89. X
  90. Xmain(argc, argv)
  91. Xchar **argv;
  92. X{
  93. X    register int nfonts, index;
  94. X    register char **res;
  95. X    
  96. X    if (argc != 2) {
  97. X        (void)write(2, "Syntax: \"fontcvt rsrcfile\"\n", 27);
  98. X        exit(1);
  99. X    }
  100. X    
  101. X    if (openresfile(argv[1]) < 0) {
  102. X        perror(argv[1]);
  103. X        exit(1);
  104. X    }
  105. X    
  106. X    /*
  107. X     * Convert each resource of type "FONT".
  108. X     */
  109. X    nfonts = countresources("FONT");
  110. X    for (index=1; index <= nfonts; index++) {
  111. X        if ((res = getindresource("FONT", index))) {
  112. X            convert(res);
  113. X            releaseresource(res);
  114. X        }
  115. X    }
  116. X    exit(0);
  117. X}
  118. X
  119. Xconvert(res)
  120. Xchar **res;
  121. X{
  122. X    struct fontrec {
  123. X        short    fonttype;
  124. X        short    firstchar;
  125. X        short    lastchar;
  126. X        short    widmax;
  127. X        short    kernmax;
  128. X        short    ndescent;
  129. X        short    frectwidth;
  130. X        short    frectheight;
  131. X        short    owtloc;
  132. X        short    ascent;
  133. X        short    descent;
  134. X        short    leading;
  135. X        short    rowwords;
  136. X        short    bitimage[1];
  137. X    };
  138. X    register short *ip;
  139. X    register char *cp;
  140. X    register int fd, i;
  141. X    register struct dispatch *d;
  142. X    register short *loctable, *owtable;
  143. X    char dig[6];
  144. X    auto int id, id0;
  145. X    char **res0;
  146. X    char fname[256], type[4];
  147. X    struct fontrec *fr;
  148. X    char *glyph;
  149. X    unsigned long reslen;
  150. X    struct header vfhdr;
  151. X    struct dispatch vfdis[NUM_DISPATCH];
  152. X
  153. X    /*
  154. X     * Find the resource corresponding to font size 0.  The name of
  155. X     * that resource is the font name.
  156. X     */
  157. X    reslen = sizeresource(res);
  158. X    getresinfo(res, &id, type, fname);
  159. X    if (reslen == 0 || (id & 0177) == 0)
  160. X        return;
  161. X    if (!(res0 = getresource("FONT", id&~0177)))
  162. X        return;
  163. X    getresinfo(res0, &id0, type, fname);
  164. X    releaseresource(res0);
  165. X    if (fname[0]) {
  166. X        for (cp=fname; *cp; cp++)
  167. X            if (isspace(*cp))
  168. X                *cp = '_';
  169. X            else if (isupper(*cp))
  170. X                *cp = tolower(*cp);
  171. X    } else
  172. X        return;
  173. X
  174. X    /*
  175. X     * Find the location table and offset/width table.
  176. X     */
  177. X    fr = (struct fontrec *)*res;
  178. X    i = sizeof(struct fontrec) / sizeof(short) - 1;
  179. X    for (ip=(short *)fr; --i >= 0; ip++)
  180. X        *ip = ntohs(*ip);
  181. X    ip += fr->rowwords*fr->frectheight;    /* skip bit image */
  182. X    loctable = ip - fr->firstchar;        /* index from firstchar, not 0 */
  183. X    owtable = loctable + (fr->lastchar - fr->firstchar + 3);
  184. X    for (i = 2*(fr->lastchar - fr->firstchar + 3); --i > 0; ip++)
  185. X        *ip = ntohs(*ip);
  186. X    if (fr->lastchar >= NUM_DISPATCH)
  187. X        fr->lastchar = NUM_DISPATCH - 1;
  188. X
  189. X    /*
  190. X     * Form the output filename (base name + font size) and create
  191. X     * the output file.
  192. X     */
  193. X    cp = dig + sizeof dig - 1;
  194. X    *cp = '\0';
  195. X    i = id & 0177;
  196. X    do {
  197. X        *--cp = "0123456789"[i%10];
  198. X        i /= 10;
  199. X    } while (cp > dig && i);
  200. X    (void)strncat(fname, ".", sizeof fname - 1);
  201. X    (void)strncat(fname, cp, sizeof fname - 1);
  202. X    fname[sizeof fname - 1] = '\0';
  203. X    if ((fd = creat(fname, 0644)) < 0) {
  204. X        perror(fname);
  205. X        return;
  206. X    }
  207. X
  208. X    /*
  209. X     * Create the vfont header.
  210. X     */
  211. X    vfhdr.magic = VFONT_MAGIC;
  212. X    vfhdr.maxx = fr->widmax;
  213. X    vfhdr.maxy = fr->ascent + fr->descent;
  214. X    vfhdr.size = (fr->lastchar-fr->firstchar+1)*vfhdr.maxy*((vfhdr.maxx+7)/8);
  215. X    vfhdr.xtend = 0;
  216. X
  217. X    /*
  218. X     * Allocate space for the font.  Not all of this space will be used,
  219. X     * since most characters are narrower than "widmax".
  220. X     */
  221. X    if (!(glyph=malloc((unsigned)vfhdr.size))) {
  222. X        perror("malloc");
  223. X        (void)close(fd);
  224. X        return;
  225. X    }
  226. X    
  227. X    /*
  228. X     * Extract the glyphs one by one.  Create zero-width entries for
  229. X     * missing glyphs.  Don't bother filling in the missing character
  230. X     * symbol.
  231. X     */
  232. X    cp = glyph + vfhdr.size;
  233. X    while (cp > glyph)
  234. X        *--cp = 0;
  235. X    for (i=0,d=vfdis; i < fr->firstchar; i++,d++) {
  236. X        d->addr = 0;
  237. X        d->nbytes = 0;
  238. X        d->up = 0;
  239. X        d->down = 0;
  240. X        d->left = 0;
  241. X        d->right = 0;
  242. X        d->width = 0;
  243. X    }
  244. X    for ( ; i <= fr->lastchar; i++,d++) {
  245. X        if (owtable[i] == -1) {
  246. X            d->addr = 0;
  247. X            d->nbytes = 0;
  248. X            d->up = 0;
  249. X            d->down = 0;
  250. X            d->left = 0;
  251. X            d->right = 0;
  252. X            d->width = 0;
  253. X        } else {
  254. X            d->addr = cp - glyph;
  255. X            d->up = fr->ascent;
  256. X            d->down = fr->descent;
  257. X            d->left = -((owtable[i]>>8)&0377) - fr->kernmax;
  258. X            d->right = (owtable[i]&0377) - d->left;
  259. X            if ((unsigned)d->left+(unsigned)d->right > fr->widmax) {
  260. X                /* font incorrectly formatted, take a guess */
  261. X                d->left = fr->kernmax;
  262. X                d->right = fr->widmax - d->left;
  263. X            }
  264. X            d->width = (owtable[i]&0377);
  265. X            d->nbytes = ((d->left + d->right+7)/8)*fr->frectheight;
  266. X            extract(cp, (char *)fr->bitimage, loctable[i],
  267. X                loctable[i+1] - loctable[i],
  268. X                fr->frectheight, fr->rowwords*2, d->nbytes/fr->frectheight);
  269. X            cp += d->nbytes;
  270. X        }
  271. X    }
  272. X    for ( ; i < NUM_DISPATCH; i++,d++) {
  273. X        d->addr = 0;
  274. X        d->nbytes = 0;
  275. X        d->up = 0;
  276. X        d->down = 0;
  277. X        d->left = 0;
  278. X        d->right = 0;
  279. X        d->width = 0;
  280. X    }
  281. X
  282. X    /*
  283. X     * Recompute "vfhdr.size" based upon the actual amount of memory
  284. X     * used.  Write the header, dispatch table, and glyphs.  Close the
  285. X     * output file and free the memory that was malloc()ed.
  286. X     */
  287. X    vfhdr.size = cp-glyph;    /* use actual size */
  288. X
  289. X    if (write(fd, (char *)&vfhdr, SZ_VFHDR) != SZ_VFHDR ||
  290. X        write(fd, (char *)vfdis, sizeof vfdis) != sizeof vfdis ||
  291. X        write(fd, glyph, cp-glyph) != cp-glyph)
  292. X            perror(fname);
  293. X    (void)close(fd);
  294. X    free(glyph);
  295. X}
  296. X
  297. Xextract(glyphp, bitimage, pos, wid, frh, rowlen, colbytes)
  298. Xregister char *glyphp;
  299. Xchar *bitimage;
  300. X{
  301. X    register char *byte;
  302. X    register int width, bitidx;
  303. X    int row;
  304. X
  305. X    /*
  306. X     * Extract the character in "bitimage" with bit width "wid"
  307. X     * and rectangle height "frh" into "glyphp".  "rowlen" is
  308. X     * the length of rows in the source bit image.
  309. X     */
  310. X    for (row=0; row < frh; row++) {
  311. X        width = wid;
  312. X        byte = bitimage + row*rowlen + pos/8;
  313. X        bitidx = pos%8;
  314. X        while (width > 0) {
  315. X            *glyphp++ = ((byte[0]&0377) << bitidx) |
  316. X                  ((byte[1]&0377) >> (8-bitidx));
  317. X            byte++;
  318. X            width -= 8;
  319. X                
  320. X        }
  321. X        if (width < 0)
  322. X            glyphp[-1] &= (0377 << -width);
  323. X        glyphp += colbytes - (wid+7)/8;
  324. X    }
  325. X}
  326. !EOF!fontcvt.c!
  327. echo x - resmgr.c
  328. sed -e 's/^X//' > resmgr.c << '!EOF!resmgr.c!'
  329. X/*
  330. X *    quick-and-dirty resource manager routines
  331. X *
  332. X * This file provides a set of routines which can open a resource file
  333. X * and perform some of the services of the Macintosh Resource Manager.
  334. X * The calling sequences are the same as those in *Inside Macintosh*.
  335. X * There is no attempt to provide read/write access to resource files
  336. X * (since that is considerably more complicated).
  337. X *
  338. X * Two "tricks" were used in the coding of these routines.  First, since
  339. X * the Macintosh uses a 68000, its byte order is the same as the Internet
  340. X * network byte order.  The routines "ntohs" and "ntohl", intended to
  341. X * convert network byte-ordered shorts and longs to native host shorts and
  342. X * longs, are used to convert between Macintosh byte ordering and native
  343. X * host byte ordering.  Second, the "get*resource" routines are supposed
  344. X * to return a "handle" to a resource.  They actually return a pointer
  345. X * to a structure containing information about the resource; the first
  346. X * element of that structure is a pointer to the resource.  This extra
  347. X * information is invisible to the caller (which can treat the returned
  348. X * value as a "handle").
  349. X *
  350. X * --John Bruner (27-May-86)
  351. X */
  352. X
  353. X#include <sys/types.h>
  354. X#include <sys/file.h>
  355. X#include <netinet/in.h>
  356. X#include <strings.h>
  357. X#include <errno.h>
  358. X
  359. Xstruct reshdr {
  360. X    u_long    rh_doff;    /* offset to resource data */
  361. X    u_long    rh_moff;    /* offset to resource map */
  362. X    u_long    rh_dlen;    /* length of resource data */
  363. X    u_long    rh_mlen;    /* length of resource map */
  364. X};
  365. X
  366. Xstruct rmaphdr {
  367. X    char    rmh_rsrv[22];    /* (reserved for internal use) */
  368. X    short    rmh_attr;    /* resource file attributes */
  369. X    u_short    rmh_toff;    /* offset to type list */
  370. X    u_short    rmh_noff;    /* offset to name list */
  371. X};
  372. X
  373. Xstruct typehdr {
  374. X    short    th_ntypes;    /* number of types - 1 */
  375. X};
  376. X
  377. Xstruct typeinfo {
  378. X    char    ti_type[4];    /* resource type */
  379. X    short    ti_nres;    /* number of resources of this type - 1 */
  380. X    u_short    ti_roff;    /* offset to reference list */
  381. X};
  382. X
  383. Xstruct refinfo {
  384. X    short    ri_id;        /* resource ID */
  385. X    u_short    ri_noff;    /* offset to name (from rmh_noff) */
  386. X    unsigned ri_attr:8,    /* resource attributes */
  387. X        ri_doff:24;    /* offset to resource */
  388. X    long    ri_handle;    /* (reserved) */
  389. X};
  390. X
  391. Xstruct name {
  392. X    char    nam_len;    /* length */
  393. X    char    nam_name[1];    /* string of length "nam_len" */
  394. X};
  395. X
  396. Xstruct reshandle {
  397. X    char    *h_res;        /* pointer to resource data */
  398. X    struct refinfo *h_refi;    /* reference information */
  399. X    struct typeinfo *h_typei; /* type information */
  400. X    u_long    h_len;        /* resource length */
  401. X};
  402. X
  403. Xstatic int resfile = -1;
  404. Xstatic struct reshdr reshdr;    /* resource header */
  405. Xstatic char *resmap;        /* resource map */
  406. Xstatic struct rmaphdr *rmaphdr;
  407. Xstatic struct typehdr *typehdr;
  408. Xstatic struct typeinfo *typeinfo;
  409. X
  410. Xextern int errno;
  411. Xextern char *malloc();
  412. Xextern u_long ntoh3();
  413. Xextern long lseek();
  414. X
  415. Xopenresfile(fname)
  416. Xchar *fname;
  417. X{
  418. X    register struct typeinfo *ti;
  419. X    register struct refinfo *ri;
  420. X    register int i;
  421. X
  422. X    /*
  423. X     * Open a resource file if one is not already open.  No provision
  424. X     * is made for having more than one file open at a time.  Read
  425. X     * in the various resource mapping structures.
  426. X     */
  427. X    if (resfile >= 0) {
  428. X        errno = EEXIST;    /* not even close to being correct */
  429. X        return(-1);
  430. X    }
  431. X    if ((resfile = open(fname, O_RDONLY)) < 0)
  432. X        return(-1);
  433. X    
  434. X    /*
  435. X     * Read the resource header.
  436. X     */
  437. X    if (read(resfile, (char *)&reshdr, sizeof reshdr) != sizeof reshdr) {
  438. X        (void)closeresfile();
  439. X        return(-1);
  440. X    }
  441. X    reshdr.rh_doff = ntohl(reshdr.rh_doff);
  442. X    reshdr.rh_moff = ntohl(reshdr.rh_moff);
  443. X    reshdr.rh_dlen = ntohl(reshdr.rh_dlen);
  444. X    reshdr.rh_mlen = ntohl(reshdr.rh_mlen);
  445. X    
  446. X    /*
  447. X     * Read the resource map.
  448. X     */
  449. X    if (!(resmap = malloc((unsigned)reshdr.rh_mlen))) {
  450. X        (void)closeresfile();
  451. X        return(-1);
  452. X    }
  453. X    if (lseek(resfile, (long)reshdr.rh_moff, L_SET) != reshdr.rh_moff ||
  454. X        read(resfile, resmap, (int)reshdr.rh_mlen) != reshdr.rh_mlen) {
  455. X        (void)closeresfile();
  456. X        resfile = -1;
  457. X        return(-1);
  458. X    }
  459. X    rmaphdr = (struct rmaphdr *)resmap;
  460. X    rmaphdr->rmh_attr = ntohs((short)rmaphdr->rmh_attr);
  461. X    rmaphdr->rmh_toff = ntohs((short)rmaphdr->rmh_toff);
  462. X    rmaphdr->rmh_noff = ntohs((short)rmaphdr->rmh_noff);
  463. X    
  464. X    typehdr = (struct typehdr *)(resmap + rmaphdr->rmh_toff);
  465. X    typehdr->th_ntypes = ntohs(typehdr->th_ntypes);
  466. X    typeinfo = (struct typeinfo *)(resmap + rmaphdr->rmh_toff +
  467. X        sizeof typehdr->th_ntypes);
  468. X    ti = typeinfo + (typehdr->th_ntypes+1);
  469. X    while (--ti >= typeinfo) {
  470. X        ti->ti_nres = ntohs(ti->ti_nres);
  471. X        ti->ti_roff = ntohs((short)ti->ti_roff);
  472. X        ri = (struct refinfo *)((char *)typehdr + ti->ti_roff);
  473. X        for (i = 0; i <= ti->ti_nres; i++, ri++) {
  474. X            ri->ri_id = ntohs(ri->ri_id);
  475. X            ri->ri_noff = ntohs((short)ri->ri_noff);
  476. X            ri->ri_doff = ntoh3((u_long)ri->ri_doff);
  477. X        }
  478. X    }
  479. X    
  480. X    /*
  481. X     * Everything is OK -- return 0 (success).
  482. X     */
  483. X    return(0);
  484. X}
  485. X
  486. Xcloseresfile()
  487. X{
  488. X    /*
  489. X     * Close the current resource file and deallocate the memory
  490. X     * we were using for its resource map.
  491. X     */
  492. X    if (resfile > 0) {
  493. X        (void)close(resfile);
  494. X        if (resmap)
  495. X            free((char *)resmap);
  496. X        return(0);
  497. X    } else
  498. X        return(-1);
  499. X}
  500. X
  501. Xcounttypes()
  502. X{
  503. X    /*
  504. X     * Count the number of types in the resource file.
  505. X     */
  506. X    if (resfile < 0) {
  507. X        errno = ENXIO;    /* another bogus error code */
  508. X        return(-1);
  509. X    }
  510. X    return(typehdr->th_ntypes+1);
  511. X}
  512. X
  513. Xgetindtype(type, index)
  514. Xchar type[4];
  515. X{
  516. X    /*
  517. X     * Get the resource type associated with the specified type index.
  518. X     */
  519. X    if (resfile < 0) {
  520. X        errno = ENXIO;
  521. X        return(-1);
  522. X    }
  523. X    if (--index >= 0 && index <= typehdr->th_ntypes) {
  524. X        (void)strncpy(type, typeinfo[index].ti_type, 4);
  525. X    } else
  526. X        (void)strncpy(type, "", 4);        
  527. X    return(0);
  528. X}
  529. X
  530. Xcountresources(type)
  531. Xchar type[4];
  532. X{
  533. X    register struct typeinfo *ti;
  534. X    
  535. X    /*
  536. X     * Return the number of resources of the specified type.
  537. X     */
  538. X    ti = typeinfo + (typehdr->th_ntypes+2);
  539. X    while (--ti >= typeinfo) {
  540. X        if (strncmp(type, ti->ti_type, 4) == 0)
  541. X            return(ti->ti_nres+1);
  542. X    }
  543. X    return(0);
  544. X}
  545. X
  546. Xstatic
  547. Xchar **
  548. Xgetres(ri, ti)
  549. Xstruct refinfo *ri;
  550. Xstruct typeinfo *ti;
  551. X{
  552. X    register long offset;
  553. X    register char *res;
  554. X    register struct reshandle *resh;
  555. X    auto u_long len;
  556. X
  557. X    /*
  558. X     * Return a handle to a resource whose reference info is "ri" and
  559. X     * whose type info is "ti".  This routine is used internally and
  560. X     * should not be called directly.
  561. X     */
  562. X    offset = reshdr.rh_doff + ri->ri_doff;
  563. X    if (lseek(resfile, offset, L_SET) == offset &&
  564. X        read(resfile, (char *)&len, sizeof len) == sizeof len &&
  565. X        (len = ntohl(len) , (res = malloc((unsigned)len)))) {
  566. X        if (!len || read(resfile, res, (int)len) == len) {
  567. X            if ((resh = (struct reshandle *)malloc(sizeof(struct reshandle)))) {
  568. X                resh->h_res = res;
  569. X                resh->h_refi = ri;
  570. X                resh->h_typei = ti;
  571. X                resh->h_len = len;
  572. X                return((char **)resh);
  573. X            } else {
  574. X                free(res);
  575. X                return((char **)0);
  576. X            }
  577. X        } else {
  578. X            free((char *)res);
  579. X            return((char **)0);
  580. X        }
  581. X    } else
  582. X        return((char **)0);
  583. X}
  584. X
  585. Xstruct typeinfo *
  586. Xgettypei(type)
  587. Xchar type[4];
  588. X{
  589. X    register struct typeinfo *ti;
  590. X
  591. X    /*
  592. X     * Get the type information associated with the named type.
  593. X     */
  594. X    for (ti=typeinfo; ti < typeinfo+typehdr->th_ntypes+2; ti++)
  595. X        if (strncmp(type, ti->ti_type, 4) == 0)
  596. X            return(ti);
  597. X    return((struct typeinfo *)0);
  598. X}
  599. X
  600. Xchar **
  601. Xgetindresource(type, index)
  602. Xchar type[4];
  603. X{
  604. X    register struct typeinfo *ti;
  605. X    register struct refinfo *ri;
  606. X
  607. X    /*
  608. X     * Get the resource (a "handle" is returned) whose type is "type"
  609. X     * and whose index is "index".
  610. X     */
  611. X    if ((ti = gettypei(type)) != (struct typeinfo *)0) {
  612. X        ri = (struct refinfo *)((char *)typehdr + ti->ti_roff);
  613. X        if (--index >= 0 && index <= ti->ti_nres)
  614. X            return(getres(ri + index, ti));
  615. X        else
  616. X            return((char **)0);
  617. X    } else
  618. X        return((char **)0);
  619. X}
  620. X
  621. Xchar **
  622. Xgetresource(type, id)
  623. Xchar type[4];
  624. X{
  625. X    register struct typeinfo *ti;
  626. X    register struct refinfo *ri;
  627. X    register int i;
  628. X
  629. X    /*
  630. X     * Get the resource (a "handle" is returned) with type "type" and
  631. X     * resource ID "id".
  632. X     */
  633. X    if ((ti = gettypei(type)) != (struct typeinfo *)0) {
  634. X        ri = (struct refinfo *)((char *)typehdr + ti->ti_roff);
  635. X        for (i=0; i <= ti->ti_nres; i++,ri++) {
  636. X            if (ri->ri_id == id)
  637. X                return(getres(ri, ti));
  638. X        }
  639. X    }
  640. X    return((char **)0);
  641. X}
  642. X
  643. Xchar **
  644. Xgetnamedresource(type, name)
  645. Xchar type[4];
  646. Xchar *name;
  647. X{
  648. X    register struct typeinfo *ti;
  649. X    register struct refinfo *ri;
  650. X    register struct name *n;
  651. X    register char *nbase;
  652. X    register int i;
  653. X
  654. X    /*
  655. X     * Get the resource (a "handle" is returned) whose type is "type"
  656. X     * and whose name is "name".
  657. X     */
  658. X    if ((ti = gettypei(type)) != (struct typeinfo *)0) {
  659. X        ri = (struct refinfo *)((char *)typehdr + ti->ti_roff);
  660. X        nbase = (char *)rmaphdr + rmaphdr->rmh_noff;
  661. X        for (i=0; i <= ti->ti_nres; i++,ri++) {
  662. X            if ((short)ri->ri_noff != -1) {
  663. X                n = (struct name *)(nbase + ri->ri_noff);
  664. X                if (strlen(name) == n->nam_len &&
  665. X                    strncmp(name, n->nam_name, n->nam_len) == 0)
  666. X                    return(getres(ri, ti));
  667. X            }
  668. X        }
  669. X    }
  670. X    return((char **)0);    
  671. X}
  672. X
  673. Xreleaseresource(res)
  674. Xchar **res;
  675. X{
  676. X    /*
  677. X     * Free the resource whose handle is "res".  Deallocate the memory
  678. X     * that it occupies.
  679. X     */
  680. X    free(*res);
  681. X    free((char *)res);
  682. X}
  683. X
  684. Xu_long
  685. Xsizeresource(res)
  686. Xchar **res;
  687. X{
  688. X    return(((struct reshandle *)res)->h_len);
  689. X}
  690. X
  691. Xgetresinfo(res, id, type, name)
  692. Xchar **res;
  693. Xint *id;
  694. Xchar type[4];
  695. Xchar *name;
  696. X{
  697. X    register struct reshandle *resh;
  698. X    register struct refinfo *ri;
  699. X    register struct name *nam;
  700. X
  701. X    /*
  702. X     * Get the resource information associated with "res" (a handle).
  703. X     */
  704. X    resh = (struct reshandle *)res;
  705. X    ri = resh->h_refi;
  706. X    *id = ri->ri_id;
  707. X    (void)strncpy(type, resh->h_typei->ti_type, 4);
  708. X    if ((short)ri->ri_noff != -1) {
  709. X        nam = (struct name *)((char *)rmaphdr + rmaphdr->rmh_noff + ri->ri_noff);
  710. X        (void)strncpy(name, nam->nam_name, nam->nam_len);
  711. X        name[nam->nam_len] = '\0';
  712. X    } else
  713. X        *name = '\0';
  714. X}
  715. X
  716. Xu_long
  717. Xntoh3(i)
  718. Xu_long i;
  719. X{
  720. X    /*
  721. X     * Try to convert a 3-byte quantity.  This routine assumes that
  722. X     * the bytes come from bytes (1,2,3) of (0,1,2,3) or from bytes
  723. X     * (3,2,1) of (3,2,1,0).
  724. X     *
  725. X     * The PDP-11 has a weird byte order for longs, and this routine
  726. X     * will certainly fail there.
  727. X     */
  728. X    if (ntohl(i) == i)        /* big-endian */
  729. X        return(i);
  730. X    else                /* little-endian */
  731. X        return(ntohl(i<<8));
  732. X}
  733. !EOF!resmgr.c!
  734. exit 0
  735. : end of shell archive
  736.